#include "dialog.h"
#include "mainwindow.h"

std::map<HWND,Dialog*> Dialog::dialogInstanceMap;

Dialog::Dialog( LPWSTR resource )
{
	_hWnd = NULL; //Will be set by ooDialogDispatcher
	_hWndParent = NULL;
	_resource = resource;
}

HWND Dialog::parent() const
{
	return _hWndParent;
}

void Dialog::setParent( HWND parent )
{
	_hWndParent = parent;
}

UINT_PTR Dialog::show()
{
	//Get the singleton instance of MainWindow.
	MainWindow *mainWindow = MainWindow::instance();

	//Activate the dialog box.
	return DialogBoxParam(
		mainWindow->hInstance(), //hInstance
		_resource, //integer id of the resource
		_hWndParent, //parent
		(DLGPROC) &Dialog::ooDispatcher, //message handler
		(LPARAM) this //extra parameters (the dialog instance)
		);
}

HWND Dialog::hWnd() const
{
	return _hWnd;
}

BOOL CALLBACK Dialog::ooDispatcher(
	HWND hWndDialog,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
	)
{
	if( uMsg == WM_INITDIALOG )
	{
		//lParam contains the initialisation data, this is the Dialog instance.
		Dialog *dialog = (Dialog*) lParam;
		if( dialog )
		{
			setDialogInstance( hWndDialog, dialog );
			dialog->_hWnd = hWndDialog;
			return dialog->handleMessage( uMsg, wParam, lParam );
		}
		return FALSE;
	}
	else
	{
		//Delegate the message.
		Dialog *dialog = dialogInstance( hWndDialog );
		if( dialog )
		{
			BOOL result = dialog->handleMessage( uMsg, wParam, lParam );
			if( result )
			{
				//The dialog is closed.
				releaseDialogInstance( hWndDialog );
			}
			return result;
		}
		return FALSE;
	}
}

Dialog* Dialog::dialogInstance( HWND hWndDialog )
{
	std::map<HWND,Dialog*>::iterator it = dialogInstanceMap.find( hWndDialog );
	if( it == dialogInstanceMap.end() )
	{
		//The instance is not available.
		return NULL;
	}
	else
	{
		return it->second;
	}
}

void Dialog::releaseDialogInstance( HWND hWndDialog )
{
	std::map<HWND,Dialog*>::iterator it = dialogInstanceMap.find( hWndDialog );
	if( it != dialogInstanceMap.end() )
	{
		dialogInstanceMap.erase( it );
	}
}

void Dialog::setDialogInstance( HWND hWndDialog, Dialog *data )
{
	std::pair<HWND,Dialog*> node( hWndDialog, data );
	dialogInstanceMap.insert( node );
}
